package cn.lic.tool.poi.excel.function.impl;

import java.math.BigDecimal;
import java.math.RoundingMode;
import org.apache.poi.ss.usermodel.Cell;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import cn.lic.tool.poi.excel.ParserUtils;
import cn.lic.tool.poi.excel.function.AbstractFunction;
import cn.lic.tool.poi.excel.function.IFunction;
import cn.lic.tool.poi.excel.function.IFunctionArgument;
import cn.lic.tool.poi.excel.function.IValue;
import cn.lic.tool.poi.excel.function.IValue.Type;
import cn.lic.tool.poi.excel.function.Range;

/**
 * 求和
 * @author T_lichuang1_kzx
 */
public class Sum extends AbstractFunction {
	
	public Sum(){}
	
	public Sum(IFunctionArgument[] args) {
		this.args = args;
	}

	/**
	 * @param args[0] 待求和的集合在context中的key
	 * @param args[1] 待求和的值的key, 缺省将直接对集合进行求和
	 * @param args[2] 结果集保留的小数点位数， -1 不限制小数点位数
	 */
	@Override
	public IFunction build(IFunctionArgument[] args) {
		return new Sum(args);
	}
	@Override
	public IValue execute(JSONObject ctx) {
		JSONArray dataList  = this.getArg(0, ctx).castValue(Type.JSON_ARRAY, IValue.EMPTY_ARRAY);
		
		int scale = this.getArg(2, ctx).castValue(Type.INT, 0);
		
		BigDecimal rs = doSum(dataList);
		
		if (scale >= 0) {
			rs = rs.setScale(scale, RoundingMode.HALF_DOWN);
		}
		return IValue.buildSValue(rs);
	}
	
	private BigDecimal doSum(JSONArray dataList) {
		BigDecimal rs = new BigDecimal(0);
		if (args.length >= 2 && args[1] != null) {
			for (int i = 0; i < dataList.size(); i++) {
				JSONObject elem = dataList.getJSONObject(i);
				BigDecimal val = this.getArg(1, elem).castValue(Type.BIG_DECIMAL);
				if (val != null) {
					rs = rs.add(val);
				}
			}
		} else {
			for (int i = 0; i < dataList.size(); i++) {
				rs = rs.add(dataList.getBigDecimal(i));
			}
		}
		return rs;
	}

	@Override
	public Range execute(JSONObject ctx, Cell cell) {
		IValue val = this.execute(ctx);
		ParserUtils.setCellValue(cell, val);
		return null;
	}
}
